//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

import { makeAutoObservable, runInAction } from 'mobx';
import type { LocalRepoInfo, HeadInfo, LocalRepoRemoteInfo, LocalRepoBranchInfo, LocalRepoTagInfo, LocalRepoStashInfo } from "@/api/local_repo";
import { list_repo, get_head_info, list_repo_branch, list_repo_tag, list_remote, list_stash } from "@/api/local_repo";
import { type WidgetInfo, list_widget } from "@/api/widget";
import { get_global_server_addr } from '@/api/client_cfg';
import { run_status, type GitStatusItem } from '@/api/git_wrap';
import { USER_TYPE_INTERNAL, type USER_TYPE } from '@/api/user';

export class GitStore {
    constructor() {
        makeAutoObservable(this);
    }

    private _repoId = "";
    private _userName = "";
    private _userType: USER_TYPE = USER_TYPE_INTERNAL;
    private _userToken = "";

    private _repoInfo: LocalRepoInfo | null = null;
    private _headInfo: HeadInfo | null = null;
    private _localBranchList: LocalRepoBranchInfo[] = [];
    private _remoteBranchList: LocalRepoBranchInfo[] = [];
    private _remoteList: LocalRepoRemoteInfo[] = [];
    private _tagList: LocalRepoTagInfo[] = [];
    private _stashList: LocalRepoStashInfo[] = [];
    private _widgetList: WidgetInfo[] = [];
    private _statusList: GitStatusItem[] = [];

    get repoId() {
        return this._repoId;
    }

    get userName() {
        return this._userName;
    }

    get userType() {
        return this._userType;
    }

    get userToken() {
        return this._userToken;
    }

    get repoInfo() {
        return this._repoInfo;
    }

    get headInfo() {
        return this._headInfo;
    }

    get localBranchList() {
        return this._localBranchList;
    }

    get remoteBranchList() {
        return this._remoteBranchList;
    }

    get remoteList() {
        return this._remoteList;
    }

    get tagList() {
        return this._tagList;
    }

    get stashList() {
        return this._stashList;
    }

    get widgetList() {
        return this._widgetList;
    }

    get statusList() {
        return this._statusList;
    }

    async loadHeadInfo() {
        if (this._repoInfo == null) {
            return;
        }
        const headInfo = await get_head_info(this._repoInfo.path);
        runInAction(() => {
            this._headInfo = headInfo;
        });
    }

    async loadBranchList() {
        if (this._repoInfo == null) {
            return;
        }
        const localList = await list_repo_branch(this._repoInfo.path, false);
        const remoteList = await list_repo_branch(this._repoInfo.path, true);
        runInAction(() => {
            this._localBranchList = localList;
            this._remoteBranchList = remoteList;
        });
    }

    async loadTagList() {
        if (this._repoInfo == null) {
            return;
        }
        const tagList = await list_repo_tag(this._repoInfo.path);
        runInAction(() => {
            this._tagList = tagList;
        });
    }

    async loadRemoteList() {
        if (this._repoInfo == null) {
            return;
        }
        const remoteList = await list_remote(this._repoInfo.path);
        runInAction(() => {
            this._remoteList = remoteList;
        });
    }

    async loadStashList() {
        if (this._repoInfo == null) {
            return;
        }
        const stashList = await list_stash(this._repoInfo.path);
        console.log(stashList);
        runInAction(() => {
            this._stashList = stashList;
        });
    }

    async loadWidgetList() {
        const addr = await get_global_server_addr();
        const res = await list_widget(addr);
        runInAction(() => {
            this._widgetList = res.widget_list.sort((a, b) => b.weight - a.weight);
        });
    }

    async loadStatusList() {
        if (this._repoInfo == null) {
            return;
        }
        const tmpList = await run_status(this._repoInfo.path);
        runInAction(() => {
            this._statusList = tmpList;
        });
    }

    async initRepo(repoId: string, userName: string, userType: USER_TYPE, userToken: string) {
        const repoList = await list_repo();
        const repo = repoList.find(item => item.id == repoId);
        if (repo == undefined) {
            return;
        }
        runInAction(() => {
            this._repoId = repoId;
            this._userName = userName;
            this._userType = userType;
            this._userToken = userToken;
            this._repoInfo = repo;
        });
        await this.loadHeadInfo();
        await this.loadBranchList();
        await this.loadTagList();
        await this.loadRemoteList();
        await this.loadStashList();
        await this.loadStatusList();
        await this.loadWidgetList();
    }
}